/*
Copyright (c) 2007-2009, Yusuke Yamamoto
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
 * Neither the name of the Yusuke Yamamoto nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY Yusuke Yamamoto ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Yusuke Yamamoto BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.ch_linghu.fanfoudroid.fanfou;

import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.database.Cursor;
import android.util.Log;

import com.ch_linghu.fanfoudroid.db.MessageTable;
import com.ch_linghu.fanfoudroid.db.TwitterDatabase;
import com.ch_linghu.fanfoudroid.db.UserInfoTable;
import com.ch_linghu.fanfoudroid.http.HttpException;
import com.ch_linghu.fanfoudroid.http.Response;

/**
 * A data class representing Basic user information element
 */
public class User extends WeiboResponse implements java.io.Serializable {

	static final String[] POSSIBLE_ROOT_NAMES = new String[] { "user",
			"sender", "recipient", "retweeting_user" };
	private Weibo weibo;
	
	 
	private String id;
	private String uname;
	private String province;
	private String city;
	private String location;
	private String face;
	private String sex;
	private int weiboCount;
	private int followersCount;
	private int followedCount;
	private String isFollowed;
	private int isVerified;
	
	
	private String content;
 
	
	///////////////////////////////////////////////////////////
	
 
	private static final long serialVersionUID = -6345893237975349030L;

	/* package */User(Response res, Weibo weibo) throws HttpException {
		super(res);
		Element elem = res.asDocument().getDocumentElement();
		init(elem, weibo);
	}

	/* package */public User(Response res, Element elem, Weibo weibo)
			throws HttpException {
		super(res);
		init(elem, weibo);
	}

	/* package */public User(JSONObject json) throws HttpException {
		super();
		init(json);
	}

	/* package */User(Response res) throws HttpException {
		super();
		init(res.asJSONObject());
	}

	User() {

	}

	private void init(JSONObject json) throws HttpException {
		try {
			
			 
			id = json.getString("uid");
			uname = json.getString("uname");
			province = json.getString("province");
			city = json.getString("city");
			location = json.getString("location");
			face = json.getString("face");
			sex = json.getString("sex");
			weiboCount = json.getInt("weibo_count");
			followersCount = json.getInt("followers_count");
			followersCount = json.getInt("followers_count");
			isFollowed = json.getString("is_followed");
			isVerified = json.getInt("is_verified");
			
			if (!json.isNull("content")) {	
			content = json.getString("content");
			}
 
 
		} catch (JSONException jsone) {
			throw new HttpException(jsone.getMessage() + ":" + json.toString(),
					jsone);
		}
	}

	private void init(Element elem, Weibo weibo) throws HttpException {
		this.weibo = weibo;
		ensureRootNodeNameIs(POSSIBLE_ROOT_NAMES, elem);
		
 
		id = getChildString("uid",elem);
		uname = getChildString("uname",elem);
		province = getChildString("province",elem);
		city = getChildString("city",elem);
		location = getChildText("location", elem);
		face = getChildString("face",elem);
		sex = getChildString("sex",elem);
		weiboCount = getChildInt("weibo_count",elem);
		followersCount = getChildInt("followers_count", elem);
		followersCount = getChildInt("followers_count",elem);
		isFollowed = getChildString("is_followed",elem);
		isVerified = getChildInt("is_verified",elem);

 
	}
	
 
	
	public String getId(){
		return id;
	}
	
	public String getUname(){
		return uname;
	}
	
	public String getProvince(){
		return province;
	}
	public String getCity(){
		return city;
	}
	
	public String getLocation(){
		return location;
	}
	
	public String getFace(){
		return face;
	}
	
	public String getSex(){
		return sex;
	}
	
	public int getWeiboCount(){
		return weiboCount;
	}
	
 
	
	public int getFollowedCount(){
		return followedCount;
	}
	
	public String getIsFollowed(){
		return isFollowed;
	}
	
//	public boolean isFollowing(){
//	    	if(isFollowed.equals("havefollow")||isFollowed.equals("eachfollow")){
//	    		return true;
//	    	}else{
//	    		return false;
//	    	}
//	}
	
	public int getIsVerified(){
		return isVerified;
	}
	
	
	public String getContent(){
		return content;
	}
 

 

	/**
	 * Returns the name of the user
	 * 
	 * @return the name of the user
	 */
 
	/**
	 * Returns the number of followers
	 * 
	 * @return the number of followers
	 * @since Weibo4J 1.0.4
	 */
	public int getFollowersCount() {
		return followersCount;
	}

	// TODO: uncomment
	// public DirectMessage sendDirectMessage(String text) throws WeiboException
	// {
	// return weibo.sendDirectMessage(this.getName(), text);
	// }

	public static List<User> constructUsers(Response res, Weibo weibo)
			throws HttpException {
		Document doc = res.asDocument();
		if (isRootNodeNilClasses(doc)) {
			return new ArrayList<User>(0);
		} else {
			try {
				ensureRootNodeNameIs("users", doc);
				// NodeList list =
				// doc.getDocumentElement().getElementsByTagName(
				// "user");
				// int size = list.getLength();
				// List<User> users = new ArrayList<User>(size);
				// for (int i = 0; i < size; i++) {
				// users.add(new User(res, (Element) list.item(i), weibo));
				// }

				// 去除掉嵌套的bug
				NodeList list = doc.getDocumentElement().getChildNodes();
				List<User> users = new ArrayList<User>(list.getLength());
				Node node;
				for (int i = 0; i < list.getLength(); i++) {
					node = list.item(i);
					if (node.getNodeName().equals("user")) {
						users.add(new User(res, (Element) node, weibo));
					}
				}

				return users;
			} catch (HttpException te) {
				if (isRootNodeNilClasses(doc)) {
					return new ArrayList<User>(0);
				} else {
					throw te;
				}
			}
		}
	}

	public static UserWapper constructWapperUsers(Response res, Weibo weibo)
			throws HttpException {
		Document doc = res.asDocument();
		if (isRootNodeNilClasses(doc)) {
			return new UserWapper(new ArrayList<User>(0), 0, 0);
		} else {
			try {
				ensureRootNodeNameIs("users_list", doc);
				Element root = doc.getDocumentElement();
				NodeList user = root.getElementsByTagName("user");
				int length = user.getLength();
				if (length == 0) {
					return new UserWapper(new ArrayList<User>(0), 0, 0);
				}
				//
				Element listsRoot = (Element) user.item(0);
				NodeList list = listsRoot.getChildNodes();
				List<User> users = new ArrayList<User>(list.getLength());
				Node node;
				for (int i = 0; i < list.getLength(); i++) {
					node = list.item(i);
					if (node.getNodeName().equals("user")) {
						users.add(new User(res, (Element) node, weibo));
					}
				}
				//
				long previousCursor = getChildLong("previous_curosr", root);
				long nextCursor = getChildLong("next_curosr", root);
				if (nextCursor == -1) { // 兼容不同标签名称
					nextCursor = getChildLong("nextCurosr", root);
				}
				return new UserWapper(users, previousCursor, nextCursor);
			} catch (HttpException te) {
				if (isRootNodeNilClasses(doc)) {
					return new UserWapper(new ArrayList<User>(0), 0, 0);
				} else {
					throw te;
				}
			}
		}
	}

	public static List<User> constructUsers(Response res) throws HttpException {
		try {
			JSONArray list = res.asJSONArray();
			int size = list.length();
			List<User> users = new ArrayList<User>(size);
			for (int i = 0; i < size; i++) {
				users.add(new User(list.getJSONObject(i)));
			}
			return users;
		} catch (JSONException jsone) {
			throw new HttpException(jsone);
		} catch (HttpException te) {
			throw te;
		}
	}

	/**
	 * 
	 * @param res
	 * @return
	 * @throws HttpException
	 */
	public static UserWapper constructWapperUsers(Response res)
			throws HttpException {
		JSONObject jsonUsers = res.asJSONObject(); // asJSONArray();
		try {
			JSONArray user = jsonUsers.getJSONArray("users");
			int size = user.length();
			List<User> users = new ArrayList<User>(size);
			for (int i = 0; i < size; i++) {
				users.add(new User(user.getJSONObject(i)));
			}
			long previousCursor = jsonUsers.getLong("previous_curosr");
			long nextCursor = jsonUsers.getLong("next_cursor");
			if (nextCursor == -1) { // 兼容不同标签名称
				nextCursor = jsonUsers.getLong("nextCursor");
			}
			return new UserWapper(users, previousCursor, nextCursor);
		} catch (JSONException jsone) {
			throw new HttpException(jsone);
		}
	}

	/**
	 * @param res
	 * @return
	 * @throws HttpException
	 */
	static List<User> constructResult(Response res) throws HttpException {
		JSONArray list = res.asJSONArray();
		try {
			int size = list.length();
			List<User> users = new ArrayList<User>(size);
			for (int i = 0; i < size; i++) {
				users.add(new User(list.getJSONObject(i)));
			}
			return users;
		} catch (JSONException e) {
		}
		return null;
	}
	
 
 

	@Override
	public int hashCode() {
		return id.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (null == obj) {
			return false;
		}
		if (this == obj) {
			return true;
		}
		return obj instanceof User && ((User) obj).id.equals(this.id);
	}


	@Override
	public String toString() {
		return "User{" + "weibo=" + weibo + ", id=" + id + ", uname='" + uname
		+ '\'' + ", province='" + province + '\'' + ", city='"
		+ city + '\'' + ", location='" + location + '\''
		+ ", face='" + face + '\'' + ", sex='"
		+ sex + '\'' + ", weiboCount=" + weiboCount
		+ ", followersCount=" + followersCount + ", followedCount="
		+ followedCount + ", isFollowed=" + isFollowed + ", isVerified='"
		+ isVerified + '\'' +
		'}';
 
	}

	// TODO:增加从游标解析User的方法，用于和data里User转换一条数据
	public static User parseUser(Cursor cursor) {
		if (null == cursor || 0 == cursor.getCount() || cursor.getCount() > 1) {
			Log.w("User.ParseUser",
					"Cann't parse Cursor, bacause cursor is null or empty.");
		}
		cursor.moveToFirst();
		User u = new User();
		u.id = cursor.getString(cursor.getColumnIndex(UserInfoTable._ID));
		u.uname = cursor.getString(cursor
				.getColumnIndex(UserInfoTable.FIELD_USER_NAME));
		u.province = cursor.getString(cursor
				.getColumnIndex(UserInfoTable.FIELD_PROVINCE));
		u.city = cursor.getString(cursor
				.getColumnIndex(UserInfoTable.FIELD_CITY));
		u.location = cursor.getString(cursor
				.getColumnIndex(UserInfoTable.FIELD_LOCALTION));
		u.face = cursor.getString(cursor
				.getColumnIndex(UserInfoTable.FIELD_FACE));
		u.sex = cursor.getString(cursor
				.getColumnIndex(UserInfoTable.FIELD_SEX));
//		u.isProtected = (0 == cursor.getInt(cursor
//				.getColumnIndex(UserInfoTable.FIELD_PROTECTED))) ? false : true;
		u.weiboCount = cursor.getInt(cursor
				.getColumnIndex(UserInfoTable.FIELD_WEIBO_COUNT));
		u.followersCount = cursor.getInt(cursor
				.getColumnIndex(UserInfoTable.FIELD_FOLLOWERS_COUNT));
		u.followedCount = cursor.getInt(cursor
				.getColumnIndex(UserInfoTable.FIELD_FOLLOWED_COUNT));
		u.isVerified = cursor.getInt(cursor
				.getColumnIndex(UserInfoTable.FIELD_IS_VERIFIED));
//		u.following = (0 == cursor.getInt(cursor
//				.getColumnIndex(UserInfoTable.FIELD_FOLLOWING))) ? false : true;
		u.isFollowed = cursor.getString(cursor
				.getColumnIndex(UserInfoTable.FIELD_IS_FOLLOWED));

//		try {
//			String createAtStr = cursor.getString(cursor
//					.getColumnIndex(MessageTable.FIELD_CREATED_AT));
//			if (createAtStr != null) {
//				u.createdAt = TwitterDatabase.DB_DATE_FORMATTER
//						.parse(createAtStr);
//			}
//
//		} catch (ParseException e) {
//			Log.w("User", "Invalid created at data.");
//		}
		return u;
	}

	public com.ch_linghu.fanfoudroid.data.User parseUser() {
		com.ch_linghu.fanfoudroid.data.User user = new com.ch_linghu.fanfoudroid.data.User();
		
		user.id = this.id;
		user.uname = this.uname;
		user.province = this.province;
		user.city = this.city;
		user.location = this.location;
		user.face = this.face;
		user.sex = this.sex;
		user.weiboCount = this.weiboCount;
		user.followersCount = this.followersCount;
		user.followedCount = this.followedCount;
		user.isVerified = this.isVerified;
		user.isFollowed =this.isFollowed;
		
 
		return user;
	}
}
